<template>
  <div class="role-container">
    <div>
      <!-- 按钮 -->
      <el-button size="small" type="primary" @click="addRole">添加角色</el-button>
    </div>
    <div class="rc-table">
      <!-- 表格 -->
      <el-table
        :data="tableData"
        style="width: 100%"
      >
        <el-table-column
          prop="name"
          label="角色"
          width="180"
        >
          <template v-slot="{row}">
            <el-input v-if="row.isEdit" v-model="currentItem.name" />
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="state"
          label="启用"
          width="180"
        >
          <template v-slot="{row}">
            <el-switch
              v-if="row.isEdit"
              v-model="currentItem.state"
              active-color="#13ce66"
              inactive-color="#ff4949"
              :active-value="1"
              :inactive-value="0"
            />
            <span v-else>{{ row.state === 1 ? '已启用': "未启用" }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="description"
          label="描述"
        >
          <template v-slot="{row}">
            <el-input v-if="row.isEdit" v-model="currentItem.description" type="textarea" />
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
        >
          <template v-slot="{row}">
            <div v-if="row.isEdit">
              <el-button size="mini" type="primary" :loading="updateLoading" @click="updateRoleTmp">确定</el-button>
              <el-button size="mini" @click="row.isEdit = false">取消</el-button>
            </div>
            <div v-else>
              <div>
                <el-button type="text" @click="fn(row.id)">分配权限</el-button>
                <el-button type="text" @click="openEditItem(row)">编辑</el-button>

                <el-popconfirm
                  class="pop-delete"
                  title="这是一段内容确定删除吗？"
                  @onConfirm="delTmp(row.id)"
                >
                  <el-button slot="reference" type="text">删除</el-button>
                </el-popconfirm>

              </div>
            </div>
          </template>
          <div slot="header">
            <el-tag type="success">操作</el-tag>
          </div>
        </el-table-column>
      </el-table>
    </div>
    <div class="rc-page">
      <!-- 分页 -->
      <!-- total所有数据的总条数 -->
      <!-- layout就是分页插件的布局，一个字符串就是一个结构 -->
      <!-- page-size就是当前页面显示多少条数据， page-sizes 每页显示多少条数据切换 -->
      <!-- current-page这是当前页码值  current-change这个事件是页码值改动自动调用的函数 -->
      <!-- handleSizeChange 每一页显示条数发生改变，触发的函数 -->
      <!-- :current-page="pageParams.page" 这句话不加，我们js里面改变了page的值，页面上面的分页插件不会自动跳转到第一页，model和view的绑定没有建立，有问题 -->
      <el-pagination
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        :page-sizes="[3, 5, 10, 50]"
        :page-size="pageParams.pagesize"
        :current-page="pageParams.page"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
    >
      <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="100px" class="demo-ruleForm">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="ruleForm.name" />
        </el-form-item>
        <el-form-item label="角色状态">
          <!--  默认是启用的,1启用状态  0未启用 -->
          <el-switch
            v-model="ruleForm.state"
            active-color="#13ce66"
            inactive-color="#ff4949"
            :active-value="1"
            :inactive-value="0"
          />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="ruleForm.description" type="textarea" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="addLoading" @click="submitForm">立即创建</el-button>
          <el-button @click="resetForm">重置</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

    <AssignPermissiton v-if="showPermisstionDialog" v-model="showPermisstionDialog" :current-id="currentId" :perm-ids="permIds" />
    <!-- <AssignPermissiton :value="showPermisstionDialog" @input="showPermisstionDialog = $event" /> -->
  </div>
</template>

<script>
import { getRolesRequest, addRoleRequest, updateRoleRequest, deleteRoleRequest, getRoleDetailByIdRequest } from '@/api/role'
import AssignPermissiton from './components/assignPermission.vue'

export default {
  name: 'RoleCom',
  components: { AssignPermissiton },
  data() {
    // data上面的数据，只要一定义，就会执行vue源码里面
    // 递归执行Object.defineproperty(data, 'total', { 转换的地方get set函数})
    // 将data里面所有的属性 转换为响应式的 get set的形式
    // 对应源码里面的 defineReactive 这个函数
    return {
      tableData: [],
      total: 0,
      pageParams: {
        page: 1,
        pagesize: 3
      },
      dialogVisible: false,
      addLoading: false,
      ruleForm: {
        name: '',
        // 默认是启用的,1启用状态  0未启用
        state: 1,
        description: ''
      },
      rules: {
        name: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        description: [
          { required: true, message: '请输入角色描述', trigger: 'blur' }
        ]
      },
      currentItem: {},
      updateLoading: false,
      // 下面变量是 分配权限的弹出框的变量
      showPermisstionDialog: false,
      currentId: null,
      permIds: []
    }
  },
  created() {
    this.getRoles()
  },
  methods: {
    async getRoles() {
      const res = await getRolesRequest(this.pageParams)
      this.tableData = res.data.rows
      // 涉及到分页的接口，后端一定要吧总条数数据告诉你，不然分页插件没法做
      this.total = res.data.total

      this.tableData.forEach(item => {
        // 给每个对象添加一个属性，isEdit 判断当前行是否是编辑状态
        // 下面这个写法，是后面给对象追加的属性，vue监听不到，所有isEdit属性就没有响应式
        // 就是 js里面的值发生了改变，但是模板的view层没有改变
        // item.isEdit = false
        // $set的底层 也就是调用Object.defineproperty
        this.$set(item, 'isEdit', false)
      })
    },
    addRole() {
      this.dialogVisible = true
    },
    async fn(id) {
      const res = await getRoleDetailByIdRequest(id)
      this.permIds = res.data.permIds

      this.showPermisstionDialog = true
      this.currentId = id
    },
    // 点击编辑按钮，打开当前行的编辑状态的函数
    openEditItem(row) {
      // 排他思想
      this.tableData.forEach(item => {
        item.isEdit = false
      })
      // 一个小bug，在编辑当前行的时候，应该先将所以的行的 isEdit编辑状态 改为false--- 同一个时间只能编辑一个
      row.isEdit = true
      // 当前编辑的数据不能是原始数据row，应该在基于row创建一个新地址，也就是一个新对象
      // 里面的内容和row一模一样 ---- 一定要有地址
      // 浅拷贝两个方法  Object.assign  ...展开运算符
      // 深拷贝几个方法  JSON.parse(JSON.stringify(obj))  lodash.cloneDeep()  递归函数自己写的不算
      this.currentItem = { ...row }
    },
    async updateRoleTmp() {
      try {
        this.updateLoading = true
        await updateRoleRequest(this.currentItem)
        // 编辑成功以后，先吧状态值改过来，然后再刷新页面（调获取列表的函数）
        await this.getRoles()

        this.updateLoading = false
      } catch (_) {
        // 下面这里一定要写，请求如果报错了，要处理这个loading
        // _ 这个变量是错误变量，我们不用，但是一定要写，不然catch就报错。
        // 如果一个变量 定义了不用，一般用 _
        this.updateLoading = false
      }
    },
    // 下面函数是 当前页码值改变，重新发请求
    handleCurrentChange(val) {
      this.pageParams.page = val
      this.getRoles()
    },
    // 下面函数是 每页显示条数发生改变，重新发请求
    handleSizeChange(val) {
      // 每次切换页面条数，当前页码值要重置为1，防止有些bug产生
      this.pageParams.page = 1
      this.pageParams.pagesize = val
      this.getRoles()
    },
    submitForm() {
      this.$refs.ruleFormRef.validate(async(valid) => {
        this.addLoading = true
        if (valid) {
          try {
            await addRoleRequest(this.ruleForm)
            this.addLoading = false
            // 如果新增成功以后，应该关闭弹窗，还应该清空或者重置表单
            this.resetForm()
            // 新增成功以后，还需要吧弹出框背后的那个页面刷新一下，本质就是调用获取角色的函数而已
            this.getRoles()
          } catch (err) {
            this.addLoading = false
          }
        } else {
          this.addLoading = false
        }
      })
    },
    resetForm() {
      this.dialogVisible = false
      this.$refs.ruleFormRef.resetFields()
    },
    async delTmp(id) {
      try {
        if (this.tableData.length === 1) {
          this.pageParams.page === 1 ? this.pageParams.page = 1 : this.pageParams.page--
        }
        // 这个页面上的事件绑定 要去 2.13.2的版本里面去看  最新的是 2.15.2
        await deleteRoleRequest(id)

        // 刷新列表页面，就是重新调用函数
        this.getRoles()
      } catch (_) {
        //
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.role-container {
  padding: 20px;
  .rc-table {
    margin: 20px 0;
  }
  .rc-page {
    text-align: right;
  }
  .pop-delete {
    margin-left: 10px;
  }
}
</style>
